package com.platform.web.lisenter;

import com.alibaba.fastjson.JSONObject;
import com.platform.base.domain.BaseLocation;
import com.platform.base.domain.ValveInfo;
import com.platform.base.service.IBaseLocationService;
import com.platform.base.service.IValveInfoService;
import com.platform.common.manager.AsyncManager;
import com.platform.common.utils.DateUtils;
import com.platform.common.utils.netty.NettyUtil;
import com.platform.common.utils.redis.RedisUtil;
import com.platform.common.utils.spring.SpringUtils;
import com.platform.data.domain.MeterRead;
import com.platform.data.domain.RuleAlarm;
import com.platform.data.domain.ValveData;
import com.platform.data.service.IEqAlarmService;
import com.platform.data.service.IMeterReadService;
import com.platform.data.service.IRuleAlarmService;
import com.platform.data.service.IValveDataService;
import com.rabbitmq.client.Channel;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.annotations.Param;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.TimerTask;
import org.apache.ibatis.annotations.Param;

@Component
@Slf4j
public class ValveListener {

    @Autowired
    private RedisUtil redisUtil;

    @RabbitListener(queues = "valve_queue")
    @RabbitHandler
    public void receiveValve(JSONObject object, Channel channel, Message message){
        try{
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
            String messageId = message.getMessageProperties().getHeaders().get("spring_returned_message_correlation").toString();
            if(redisUtil.hasKey("message:"+messageId)){
                return;
            }
            redisUtil.set("message:"+messageId, messageId, 1000);
            //执行异步保存数据
            log.info("执行异步保存阀门数据："+ object.getString("datas"));
            AsyncManager.me().execute(ValvePoolTask.saveValve(object.getString("datas"), object.getDate("createTime"),object.getString("clientId")));
        }catch (IOException e){
            e.printStackTrace();
        }
    }
}

/**
 * 异步任务保存阀门数据
 */
@Slf4j
class ValvePoolTask {


    public static TimerTask saveValve(final String datas, final Date createTime,final String clientId) {
        IValveDataService valveDataService = SpringUtils.getBean(IValveDataService.class);
        IValveInfoService valveInfoService = SpringUtils.getBean(IValveInfoService.class);
        IBaseLocationService baseLocationService = SpringUtils.getBean(IBaseLocationService.class);
        IMeterReadService meterReadService =SpringUtils.getBean(IMeterReadService.class);
        IRuleAlarmService ruleAlarmService =SpringUtils.getBean(IRuleAlarmService.class);
        log.info("阀门数据=========="+datas);

        return new TimerTask() {
            @Override
            public void run() {
                String[] contents = datas.split(" ");
                //阀id
                String valveId = contents[2] + contents[1];
                String collectorId = clientId;
                ValveInfo info = valveInfoService.selectValveInfoBytId(valveId,collectorId);
               /* List<ValveInfo> valveInfos= Collections.singletonList(info);
                  if   (valveInfos.size()>'1'){
                 System.out.println("ceshicuowu");

                  };*/
                valveId=info.getValveId();
                BaseLocation baseLocation = baseLocationService.selectBaseLocationById(String.valueOf(info.getLocationId()));
                MeterRead meterRead = meterReadService.selectMeterCheckList(String.valueOf(info.getLocationId()));
                RuleAlarm ruleAlarm = ruleAlarmService.selectalarmlimits("1");
                RuleAlarm ruleAlarma = ruleAlarmService.selectalarmlimits("2");
                RuleAlarm ruleAlarmb = ruleAlarmService.selectalarmlimits("3");
                RuleAlarm ruleAlarmc = ruleAlarmService.selectalarmlimits("4");
                RuleAlarm ruleAlarmd = ruleAlarmService.selectalarmlimits("5");
                RuleAlarm ruleAlarme = ruleAlarmService.selectalarmlimits("6");
                RuleAlarm ruleAlarmf = ruleAlarmService.selectalarmlimits("7");
                RuleAlarm ruleAlarmg = ruleAlarmService.selectalarmlimits("8");
                RuleAlarm ruleAlarmh = ruleAlarmService.selectalarmlimits("21");

                try {
                    //阀温度上限
                    String max = NettyUtil.get10HexNum(contents[3]) + "." + NettyUtil.get10HexNum(contents[4]);
                    //阀温度下限
                    String min = NettyUtil.get10HexNum(contents[5]) + "." + NettyUtil.get10HexNum(contents[6]);
                    //阀温度值
                    String temp = NettyUtil.get10HexNum(contents[7]) * 0.5 + "";
                    //室内温度
                    String indoor = NettyUtil.get10HexNum(contents[10]) + "." + NettyUtil.get10HexNum(contents[9]);
                    //gnbz
                    int heatStatus = NettyUtil.get10HexNum(contents[8]);
                    //工作时间
                    String work = NettyUtil.get10HexNum(contents[13] + contents[14] + contents[15]) + "";
                    //阀控温上限
                    String tempmax = NettyUtil.get10HexNum(contents[21]) * 0.5 + "";
                    //阀开度上限
                    String openmax = NettyUtil.get10HexNum(contents[30]) + "";
                    //阀开度下限
                    String openmin = NettyUtil.get10HexNum(contents[31]) + "";
                    //阀开度
                    String open = NettyUtil.get10HexNum(contents[34]) + "";
                    //回水温度使能
                    String outletStatus = NettyUtil.get10HexNum(contents[18]) + "";

                    //回水温度
                    String outlet = (NettyUtil.get10HexNum(contents[19] + contents[20]))/10 + "";

                    //错误码
                    int error = NettyUtil.get10HexNum(contents[33]);

                    ValveData valveData = new ValveData();
                    valveData.setValveId(valveId);
                    valveData.setMax(max);
                    valveData.setMin(min);
                    valveData.setTemp(temp);
                    valveData.setIndoor(indoor);
                    valveData.setWorkTime(work);
                    valveData.setAperture(open);
                    valveData.setAperturemax(openmax);
                    valveData.setAperturemin(openmin);
                    valveData.setTempmax(tempmax);
                    valveData.setCollectorId(collectorId);
                    valveData.setOnlineStatus(1);
                    valveData.setOutlet(outlet);
                    valveData.setOutletStatus(outletStatus);
                    if(createTime==null) {
                        valveData.setCreateTime(DateUtils.getNowDate());
                    }else{
                        valveData.setCreateTime(createTime);
                    }
                    if(heatStatus == 102){
                        valveData.setHeatStatus(0);
                    }else{
                        valveData.setHeatStatus(1);
                    }
                    if((error & 1) == 1){
                        log.error( "阀门" + valveId + "EEPROM写入故障");
                        AsyncManager.me().execute(AlarmPoolTask.saveAlarm(valveId,String.valueOf(info.getLocationId()), "1", "2", "EEPROM写入故障", "阀门"+valveId+"EEPROM写入故障"));
                    }else if((error & 2) == 2){
                        log.error( "阀门" + valveId + "电机故障");
                        AsyncManager.me().execute(AlarmPoolTask.saveAlarm(valveId,String.valueOf(info.getLocationId()), "1", "2", "电机故障", "阀门"+valveId+"电机故障"));
                    }else if((error & 4) == 4){
                        log.error( "阀门" + valveId + "无线丢失");
                        AsyncManager.me().execute(AlarmPoolTask.saveAlarm(valveId,String.valueOf(info.getLocationId()), "1", "3", "无线丢失", "阀门"+valveId+"无线丢失"));
                        valveData.setOnlineStatus(0);
                    }else if((error & 8) == 8){
                        log.error( "阀门" + valveId + "储能电路故障");
                        AsyncManager.me().execute(AlarmPoolTask.saveAlarm(valveId, String.valueOf(info.getLocationId()),"1", "3", "储能电路故障", "阀门"+valveId+"储能电路故障"));
                    }else if((error & 16) == 16){
                        log.error( "阀门" + valveId + "阀锈死或者卡死");
                        AsyncManager.me().execute(AlarmPoolTask.saveAlarm(valveId,String.valueOf(info.getLocationId()), "1", "2", "阀锈死或者卡死", "阀门"+valveId+"阀锈死或者卡死"));
                    }else if((error & 32) == 32){
                        log.error( "阀门" + valveId + "自学故障");
                        AsyncManager.me().execute(AlarmPoolTask.saveAlarm(valveId, String.valueOf(info.getLocationId()),"1", "2", "自学故障", "阀门"+valveId+"自学故障"));
                    }
                    valveDataService.insertValveData(valveData);


                    if(baseLocation.getStatus().equals("1") && Float.parseFloat(indoor) < Float.parseFloat(ruleAlarmc.getAlarmLimitsf())){
                        log.error( "缴费用户" + baseLocation.getLocationName()  + "室温低于"+ruleAlarmc.getAlarmLimitsf()+"摄氏度");
                        AsyncManager.me().execute(AlarmPoolTask.saveAlarm(valveId, String.valueOf(info.getLocationId()),"5", "1", "缴费用户室温低于"+ruleAlarmc.getAlarmLimitsf()+"摄氏度", "缴费用户" +baseLocation.getLocationName()+"室温为"+indoor+"室温低于"+ruleAlarmc.getAlarmLimitsf()+"摄氏度"));
                    }
                    if(baseLocation.getStatus().equals("1") && Float.parseFloat(indoor) < Float.parseFloat(ruleAlarme.getAlarmLimitsf())){
                       log.error("缴费用户" + baseLocation.getLocationName()  + "室温低于"+ruleAlarme.getAlarmLimitsf()+"摄氏度");
                       AsyncManager.me().execute(AlarmPoolTask.saveAlarm(valveId, String.valueOf(info.getLocationId()),"5", "2", "缴费用户室温低于"+ruleAlarme.getAlarmLimitsf()+"摄氏度", "缴费用户"+baseLocation.getLocationName()+"室温为"+indoor+"室温低于"+ruleAlarme.getAlarmLimitsf()+"摄氏度"));

                    }
                    if(meterRead != null) {
                        if (baseLocation.getStatus().equals("1") && Float.parseFloat(open) != Float.parseFloat(ruleAlarma.getAlarmLimits()) && Float.parseFloat(meterRead.getInstant()) < Float.parseFloat(ruleAlarma.getAlarmLimitsf())) {
                            log.error("用户" + info.getLocationName() + "缴费用户，阀开度不为零，流量小于"+ruleAlarma.getAlarmLimitsf());
                            AsyncManager.me().execute(AlarmPoolTask.saveAlarm(valveId, String.valueOf(info.getLocationId()), "5", "1", "缴费用户，阀开度不为零，流量小于"+ruleAlarma.getAlarmLimitsf(), "缴费用户" + baseLocation.getLocationName() + "阀开度不为零，流量小于"+ruleAlarma.getAlarmLimitsf()));
                        }
                    }
                    if(meterRead != null) {
                        if (Float.parseFloat(open) == Float.parseFloat(ruleAlarmf.getAlarmLimits()) && Float.parseFloat(meterRead.getInstant()) >Float.parseFloat(ruleAlarmf.getAlarmLimitsf())) {
                            log.error("用户" + info.getLocationName() + "阀开度为零，流量大于"+ruleAlarmf.getAlarmLimitsf());
                            AsyncManager.me().execute(AlarmPoolTask.saveAlarm(valveId, String.valueOf(info.getLocationId()), "5", "2", "阀开度为零，流量大于"+ruleAlarmf.getAlarmLimitsf(), "用户" + baseLocation.getLocationName() + "阀开度为零，流量大于"+ruleAlarmf.getAlarmLimitsf()));
                        }
                    }
                    if(meterRead != null) {
                    if(Float.parseFloat(open)>Float.parseFloat(ruleAlarmg.getAlarmLimits()) && Float.parseFloat(meterRead.getInstant()) <Float.parseFloat(ruleAlarmg.getAlarmLimitsf()) ){
                        log.error("用户" + info.getLocationName() + "阀开度大于"+ruleAlarmg.getAlarmLimits()+ "，流量小于"+ruleAlarmg.getAlarmLimitsf());
                        AsyncManager.me().execute(AlarmPoolTask.saveAlarm(valveId, String.valueOf(info.getLocationId()),"5", "3", "阀开度大于"+ruleAlarmg.getAlarmLimits()+ "，流量小于"+ruleAlarmg.getAlarmLimitsf(), "用户"+baseLocation.getLocationName()+"阀开度大于50%，流量小于"+ruleAlarmg.getAlarmLimitsf()));
                        }
                    }
                    if(meterRead != null) {
                        if(Float.parseFloat(open) == Float.parseFloat(ruleAlarmh.getAlarmLimits()) && Float.parseFloat(meterRead.getInstant()) == Float.parseFloat(ruleAlarmh.getAlarmLimitsf()) ){
                            log.error("缴费用户" + info.getLocationName() + "阀开度等于"+ruleAlarmh.getAlarmLimits()+ "，流量等于"+ruleAlarmh.getAlarmLimitsf());
                            AsyncManager.me().execute(AlarmPoolTask.saveAlarm(valveId, String.valueOf(info.getLocationId()),"5", "3", "缴费用户，阀开度等于"+ruleAlarmh.getAlarmLimits()+ "，流量等于"+ruleAlarmh.getAlarmLimitsf(), "缴费用户，阀开度等于"+ruleAlarmh.getAlarmLimits()+ "，流量等于"+ruleAlarmh.getAlarmLimitsf()));
                        }
                    }




                }catch (Exception e){
                    e.printStackTrace();

                    AsyncManager.me().execute(AlarmPoolTask.saveAlarm(valveId,String.valueOf(info.getLocationId()), "1", "3", "采集阀门数据", "阀门"+valveId+"数据["+datas+"]有误，解析错误"+e.getMessage()));
                }
            }
        };
    }
}
